package yun.service;

import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnInfoListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.media.MediaPlayer.OnSeekCompleteListener;
import android.os.IBinder;

public class MediaPlayerService extends Service implements OnSeekCompleteListener, OnCompletionListener, OnInfoListener, OnErrorListener, OnPreparedListener {

	enum State {
		IDLE,
		PLAYED,
		PAUSED,
		STOPPED,
		RELEASED,
	}

	State mState;
	boolean mShuffle;
	boolean mRepeat;
	boolean mLoop;
	boolean mAutoStart;

	MediaPlayer mPlayer;
	Playlist<Long> mPlaylist;

	@Override
	public void onCreate() {
		mPlayer = new MediaPlayer();
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		setState(State.RELEASED);
		mPlayer.release();
	}

	public IBinder onBind(Intent intent) {
		return null;
	}

	public void setState(State state) {
		mState = state;
	}

	/*
	 * Main actions
	 */
	void setTracks(long[] array) {
		setTracks(-1, array);
	}
	void setTracks(int index, long[] array) {
		if (0 < index) {
			mPlaylist = PlaylistFactory.createPlaylist(index, array, mRepeat, mShuffle);
		} else {
			mShuffle = true;
			mPlaylist = PlaylistFactory.createShufflePlaylist(array, mRepeat);
		}
	}
	void play() {
		switch (mState) {
		case PAUSED:
			setState(State.PLAYED);
			mPlayer.start();
			break;
		case STOPPED:
			setState(State.PLAYED);
			setInitialize(mPlaylist.current());
			break;
		}
	}
	void pause() {
		switch (mState) {
		case PLAYED:
			setState(State.PAUSED);
			mPlayer.pause();
			break;
		}
	}
	void seekTo(int time) {
		switch (mState) {
		case PLAYED:
		case PAUSED:
			mPlayer.seekTo(time);
			break;
		}
	}
	void next() {
		switch (mState) {
		case PLAYED:
			if (mPlaylist.hasNext()) {
				setInitialize(mPlaylist.next());
			}
			break;
		case PAUSED:
			if (mPlaylist.hasNext()) {
				setInitialize(mPlaylist.next());
			}
			break;
		}
	}
	void prev() {
		switch (mState) {
		case PLAYED:
			if (mPlaylist.hasPrevious()) {
				mAutoStart = true;
				setInitialize(mPlaylist.prev());
			}
			break;
		case PAUSED:
			if (mPlaylist.hasPrevious()) {
				mAutoStart = false;
				setInitialize(mPlaylist.prev());
			}
			break;
		}
	}

	void setLoop(boolean loop) {
		mPlayer.setLooping(loop);
	}

	/*
	 * Sub action
	 */
	void setInitialize(long id) {

		switch (mState) {
		case PLAYED:
			// notify play :btn pause
			break;
		case PAUSED:
			// notify play : btn play
			break;
		}

		mPlayer.reset();
		mPlayer.setOnCompletionListener(this);
		mPlayer.setOnInfoListener(this);
		mPlayer.setOnErrorListener(this);
		mPlayer.setOnPreparedListener(this);
		mPlayer.setOnSeekCompleteListener(this);

		try {
			mPlayer.setDataSource("current path");
		} catch (Exception e) {
			return;
		}

		mPlayer.prepareAsync();
	}
	
	/*
	 * Callbacks
	 */

	@Override
	public void onPrepared(MediaPlayer player) {
		switch (mState) {
		case PLAYED:
			mPlayer.start();
			break;
		}
	}

	@Override
	public boolean onError(MediaPlayer player, int what, int code) {
		mPlayer.stop();
		return true;
	}

	@Override
	public boolean onInfo(MediaPlayer player, int what, int code) {
		return false;
	}

	@Override
	public void onCompletion(MediaPlayer player) {
		if (mPlaylist.hasNext()) {
			setInitialize(mPlaylist.next());
		} else {
			mPlayer.stop();
		}
	}

	@Override
	public void onSeekComplete(MediaPlayer player) {
		switch (mState) {
		case PLAYED:
			mPlayer.start();
			break;
		}
	}

	/*
	 * notify
	 */

	void notifyInitialize() {
	}
	void notifyError() {
	}
	void notifyPlayed() {
	}
	void notifyPaused() {
	}
	void notifyChangedTime() {
	}
}
